home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / TEXTURE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.4 KB  |  246 lines

  1.  
  2. /* texture.c - by David Blythe, SGI */
  3.  
  4. /* read_texture is a simplistic routine for reading an SGI .rgb image file. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h> 
  8. #include <string.h>
  9.  
  10. void
  11. bwtorgba(unsigned char *b,unsigned char *l,int n) {
  12.     while(n--) {
  13.         l[0] = *b;
  14.         l[1] = *b;
  15.         l[2] = *b;
  16.         l[3] = 0xff;
  17.         l += 4; b++;
  18.     }
  19. }
  20.  
  21. void
  22. rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  23.     while(n--) {
  24.         l[0] = r[0];
  25.         l[1] = g[0];
  26.         l[2] = b[0];
  27.         l[3] = 0xff;
  28.         l += 4; r++; g++; b++;
  29.     }
  30. }
  31.  
  32. void
  33. rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
  34.     while(n--) {
  35.         l[0] = r[0];
  36.         l[1] = g[0];
  37.         l[2] = b[0];
  38.         l[3] = a[0];
  39.         l += 4; r++; g++; b++; a++;
  40.     }
  41. }
  42.  
  43. typedef struct _ImageRec {
  44.     unsigned short imagic;
  45.     unsigned short type;
  46.     unsigned short dim;
  47.     unsigned short xsize, ysize, zsize;
  48.     unsigned int min, max;
  49.     unsigned int wasteBytes;
  50.     char name[80];
  51.     unsigned long colorMap;
  52.     FILE *file;
  53.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  54.     unsigned long rleEnd;
  55.     unsigned int *rowStart;
  56.     int *rowSize;
  57. } ImageRec;
  58.  
  59. static void
  60. ConvertShort(unsigned short *array, unsigned int length) {
  61.     unsigned short b1, b2;
  62.     unsigned char *ptr;
  63.  
  64.     ptr = (unsigned char *)array;
  65.     while (length--) {
  66.         b1 = *ptr++;
  67.         b2 = *ptr++;
  68.         *array++ = (b1 << 8) | (b2);
  69.     }
  70. }
  71.  
  72. static void
  73. ConvertUint(unsigned *array, unsigned int length) {
  74.     unsigned int b1, b2, b3, b4;
  75.     unsigned char *ptr;
  76.  
  77.     ptr = (unsigned char *)array;
  78.     while (length--) {
  79.         b1 = *ptr++;
  80.         b2 = *ptr++;
  81.         b3 = *ptr++;
  82.         b4 = *ptr++;
  83.         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  84.     }
  85. }
  86.  
  87. static ImageRec *ImageOpen(char *fileName)
  88. {
  89.     union {
  90.         int testWord;
  91.         char testByte[4];
  92.     } endianTest;
  93.     ImageRec *image;
  94.     int swapFlag;
  95.     int x;
  96.  
  97.     endianTest.testWord = 1;
  98.     if (endianTest.testByte[0] == 1) {
  99.         swapFlag = 1;
  100.     } else {
  101.         swapFlag = 0;
  102.     }
  103.  
  104.     image = (ImageRec *)malloc(sizeof(ImageRec));
  105.     if (image == NULL) {
  106.         fprintf(stderr, "Out of memory!\n");
  107.         exit(1);
  108.     }
  109.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  110.         perror(fileName);
  111.         exit(1);
  112.     }
  113.  
  114.     fread(image, 1, 12, image->file);
  115.  
  116.     if (swapFlag) {
  117.         ConvertShort(&image->imagic, 6);
  118.     }
  119.  
  120.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  121.     image->tmpR = (unsigned char *)malloc(image->xsize*256);
  122.     image->tmpG = (unsigned char *)malloc(image->xsize*256);
  123.     image->tmpB = (unsigned char *)malloc(image->xsize*256);
  124.     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
  125.         image->tmpB == NULL) {
  126.         fprintf(stderr, "Out of memory!\n");
  127.         exit(1);
  128.     }
  129.  
  130.     if ((image->type & 0xFF00) == 0x0100) {
  131.         x = image->ysize * image->zsize * (int) sizeof(unsigned);
  132.         image->rowStart = (unsigned *)malloc(x);
  133.         image->rowSize = (int *)malloc(x);
  134.         if (image->rowStart == NULL || image->rowSize == NULL) {
  135.             fprintf(stderr, "Out of memory!\n");
  136.             exit(1);
  137.         }
  138.         image->rleEnd = 512 + (2 * x);
  139.         fseek(image->file, 512, SEEK_SET);
  140.         fread(image->rowStart, 1, x, image->file);
  141.         fread(image->rowSize, 1, x, image->file);
  142.         if (swapFlag) {
  143.             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
  144.             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
  145.         }
  146.     }
  147.     return image;
  148. }
  149.  
  150. static void
  151. ImageClose(ImageRec *image) {
  152.     fclose(image->file);
  153.     free(image->tmp);
  154.     free(image->tmpR);
  155.     free(image->tmpG);
  156.     free(image->tmpB);
  157.     free(image);
  158. }
  159.  
  160. static void
  161. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  162.     unsigned char *iPtr, *oPtr, pixel;
  163.     int count;
  164.  
  165.     if ((image->type & 0xFF00) == 0x0100) {
  166.         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  167.         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  168.               image->file);
  169.  
  170.         iPtr = image->tmp;
  171.         oPtr = buf;
  172.         for (;;) {
  173.             pixel = *iPtr++;
  174.             count = (int)(pixel & 0x7F);
  175.             if (!count) {
  176.                 return;
  177.             }
  178.             if (pixel & 0x80) {
  179.                 while (count--) {
  180.                     *oPtr++ = *iPtr++;
  181.                 }
  182.             } else {
  183.                 pixel = *iPtr++;
  184.                 while (count--) {
  185.                     *oPtr++ = pixel;
  186.                 }
  187.             }
  188.         }
  189.     } else {
  190.         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  191.               SEEK_SET);
  192.         fread(buf, 1, image->xsize, image->file);
  193.     }
  194. }
  195.  
  196. unsigned *
  197. read_texture(char *name, int *width, int *height, int *components) {
  198.     unsigned *base, *lptr;
  199.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  200.     ImageRec *image;
  201.     int y;
  202.  
  203.     image = ImageOpen(name);
  204.     
  205.     if(!image)
  206.         return NULL;
  207.     (*width)=image->xsize;
  208.     (*height)=image->ysize;
  209.     (*components)=image->zsize;
  210.     base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
  211.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  212.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  213.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  214.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  215.     if(!base || !rbuf || !gbuf || !bbuf)
  216.       return NULL;
  217.     lptr = base;
  218.     for(y=0; y<image->ysize; y++) {
  219.         if(image->zsize>=4) {
  220.             ImageGetRow(image,rbuf,y,0);
  221.             ImageGetRow(image,gbuf,y,1);
  222.             ImageGetRow(image,bbuf,y,2);
  223.             ImageGetRow(image,abuf,y,3);
  224.             rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
  225.             lptr += image->xsize;
  226.         } else if(image->zsize==3) {
  227.             ImageGetRow(image,rbuf,y,0);
  228.             ImageGetRow(image,gbuf,y,1);
  229.             ImageGetRow(image,bbuf,y,2);
  230.             rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
  231.             lptr += image->xsize;
  232.         } else {
  233.             ImageGetRow(image,rbuf,y,0);
  234.             bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
  235.             lptr += image->xsize;
  236.         }
  237.     }
  238.     ImageClose(image);
  239.     free(rbuf);
  240.     free(gbuf);
  241.     free(bbuf);
  242.     free(abuf);
  243.  
  244.     return (unsigned *) base;
  245. }
  246.